package com.minidb.engine;

import java.util.List;

import com.minidb.utils.Condition;
import com.minidb.utils.StatementType;

public class ExecutionPlan {
    // Statement type (SELECT, INSERT, CREATE_TABLE, DELETE)
    public StatementType type;
    // Target table name
    public String tableName;
    // Columns involved (projection list for SELECT, or columns provided in INSERT). Empty list means all columns.
    public List<String> columns;
    // Column types (for CREATE_TABLE)
    public List<String> columnTypes;
    // Values for INSERT (list of literal values as strings)
    public List<String> values;
    // WHERE condition for SELECT/DELETE (null if none)
    public Condition condition;

    public ExecutionPlan() {
        // default constructor
    }

    @Override
    public String toString() {
        // Represent the plan as a sequence of physical operators
        StringBuilder sb = new StringBuilder();
        if (type == StatementType.SELECT) {
            sb.append("SeqScan(").append(tableName).append(")");
            if (condition != null) {
                sb.append(" -> Filter(").append(condition).append(")");
            }
            sb.append(" -> Project(");
            if (columns == null || columns.isEmpty()) {
                sb.append("*");
            } else {
                sb.append(String.join(",", columns));
            }
            sb.append(")");
        } else if (type == StatementType.INSERT) {
            sb.append("Insert(").append(tableName).append(")");
        } else if (type == StatementType.CREATE_TABLE) {
            sb.append("CreateTable(").append(tableName).append(")");
        } else if (type == StatementType.DELETE) {
            sb.append("SeqScan(").append(tableName).append(")");
            if (condition != null) {
                sb.append(" -> Delete(where ").append(condition).append(")");
            } else {
                sb.append(" -> Delete(all)");
            }
        } else {
            sb.append("ExecutionPlan{").append(type).append("}");
        }
        return sb.toString();
    }
}
